%%

%byaccj

%{
  private Parser yyparser;
	public static final boolean debug = false;

  public Yylex(java.io.Reader r, Parser yyparser) {
    this(r);
    this.yyparser = yyparser;
	}
	
	public int yyline()
	{
		return yyline;
	}
%}


letter							=			[a-zA-Z]
digit								=			[0-9]
identifier					=			{letter}({letter}|{digit}|"_")*
integer							=			{digit}+
decimal1						=			{digit}+\.{digit}*
decimal2   					=			\.{digit}+ 

EndOfLine						=			\r|\n|\r\n
InputCharacter			=			[^\r\n]

MLComment						=			"/*" [^*] ~"*/" | "/*" "*"+ "/"
SLComment						=			"//" {InputCharacter}* {EndOfLine}?

/* comments */
Comment 						=			{MLComment} | {SLComment} 

IntegerLiteral			=			0 | "-"? [1-9][0-9]*
DecimalLiteral 			=			"-"? ({integer}|{decimal1}|{decimal2})

StringLiteral				=			"\"" ([^\"\\\n\r\t] | \\.)* "\""
CharacterLiteral		=			"\'" ([^\"\\\n\r\t] | \\.) "\'"

%%

	/*	keywords	*/
	"array"												 { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.ARRAY;  }
	"bar"													 { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.BAR; }
  "boolean"                      { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.BOOLEAN; }
  "break"                        { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.BREAK; }
  "case"                         { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.CASE; }
  "character"	                   { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.CHARACTER; }
  "continue"                     { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.CONTINUE; }
  "do"                           { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.DO; }
  "decimal"                      { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.DECIMAL; }
  "default"                      { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.DEFAULT; }
  "else"                         { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.ELSE; }
  "for"                          { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.FOR; }
	"gradient"										 { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.GRADIENT; }
	"hide"												 { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.HIDE; }
  "integer"                      { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.INTEGER; }
  "if"                           { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.IF; }
	"matrix"											 { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.MATRIX; }
	"pause"											   { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.PAUSE; }
  "return"                       { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.RETURN; }
  "switch"                       { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.SWITCH; }
	"show"												 { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.SHOW; }
	"stepall"											 { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.STEPALL; }
	"timestep"										 { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.TIMESTEP; }
  "void"                         { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.VOID; }
  "while"                        { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.WHILE; }
  "swap"                         {
																		if(debug) 
																			System.out.println("identifier = "+yytext());
																		yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1));  return Parser.SWAP; 
																 }
  
  /* boolean literals */
  "true"                         { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.TRUE; }
  "false"                        { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.FALSE; }
  
  /* null literal */
  "null"                         { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.NULL; }
  
  /* separators */
  "("                            { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.LP; }
  ")"                            { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.RP; }
  "{"                            { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.LCB; }
  "}"                            { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.RCB; }
  "["                            { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.LSB; }
  "]"                            { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.RSB; }
  ";"                            { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.SEMICOLON; }
  ","                            { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.COMMA; }
  "."                            { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.DOT; }
   
  /* operators */
  "="                            { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.EQ; }
  ">"                            { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.GT; }
  "<"                            { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.LT; }
  "!"                            { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.NOT; }
  "=="                           { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.EQEQ; }
  "<="                           { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.LTE; }
  ">="                           { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.GTE; }
  "!="                           { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.NOTEQ; }
  "&&"                           { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.AND; }
  "||"                           { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.OR; }
  "++"                           { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.INCR; }
  "--"                           { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.DECR; }
  "+"                            { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.PLUS; }
  "-"                            { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.MINUS; }
  "*"                            { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.INTO; }
  "/"                            { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.BY; }
  "%"                            { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.MOD; }
  "+="                           { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.PLUSEQ; }
  "-="                           { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.MINUSEQ; }
  "*="                           { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.INTOEQ; }
  "/="                           { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.BYEQ; }
  "%="                           { yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); return Parser.MODEQ; }

  {Comment}                      { /* ignore */ }

	{IntegerLiteral}							 {
																		if(debug) 
																			System.out.println("integer literal = "+yytext());
																		yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1));
	         													return Parser.INTCONST; 
																 }
	{DecimalLiteral}							 { 
																		if(debug) 												
																			System.out.println("decimal literal = "+yytext());
																		yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); 
																		return Parser.DECCONST; 
																 }
	{StringLiteral}								 { 
																		if(debug) 
																			System.out.println("String literal = "+yytext());
																		yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); 
																		return Parser.STRINGCONST; 
																 }
	{CharacterLiteral}						 { 
																		if(debug) 
																			System.out.println("Character literal = "+yytext()); 
																		yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1));
																		return Parser.CHARCONST; 
																 }

  {identifier}                   { 
																		if(debug) 
																			System.out.println("identifier = "+yytext());
																		yyparser.yylval = new ParserVal(new AVLNode(yytext(), yyline+1)); 
																		return Parser.IDENT; 
																 }
	{EndOfLine}										 { yyline++; }
  [ \t\f]                   		 { /* ignore */ }
	.															 { 
																		//System.out.println("Syntax Error at "+yytext()); 
																		//return -1; 
																 }
